#!/bin/bash

# SmartInput 服务启动脚本
# 一键启动所有服务：WebSocket服务器 + 移动端PWA应用

set -e  # 遇到错误立即退出

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 项目根目录
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SERVER_DIR="$PROJECT_ROOT/server"
MOBILE_DIR="$PROJECT_ROOT/mobile-app"
ADMIN_DIR="$PROJECT_ROOT/admin-panel"

# PID文件路径
PIDS_DIR="$PROJECT_ROOT/.pids"
SERVER_PID_FILE="$PIDS_DIR/server.pid"
MOBILE_PID_FILE="$PIDS_DIR/mobile.pid"
ADMIN_PID_FILE="$PIDS_DIR/admin.pid" # 新增管理后台PID文件

# 日志文件路径
LOGS_DIR="$PROJECT_ROOT/logs"
SERVER_LOG="$LOGS_DIR/server.log"
MOBILE_LOG="$LOGS_DIR/mobile.log"
ADMIN_LOG="$LOGS_DIR/admin.log" # 新增管理后台日志文件

# 创建必要的目录
mkdir -p "$PIDS_DIR" "$LOGS_DIR"

# 打印带颜色的消息
print_message() {
    local color=$1
    local message=$2
    echo -e "${color}${message}${NC}"
}

# 检查端口是否被占用
check_port() {
    local port=$1
    if lsof -Pi :$port -sTCP:LISTEN -t >/dev/null 2>&1; then
        return 0  # 端口被占用
    else
        return 1  # 端口空闲
    fi
}

# 等待端口启动
wait_for_port() {
    local port=$1
    local service_name=$2
    local max_attempts=30
    local attempt=0
    
    print_message $YELLOW "等待 $service_name 启动 (端口 $port)..."
    
    while [ $attempt -lt $max_attempts ]; do
        if check_port $port; then
            print_message $GREEN "✅ $service_name 已启动 (端口 $port)"
            return 0
        fi
        sleep 1
        attempt=$((attempt + 1))
        echo -n "."
    done
    
    print_message $RED "❌ $service_name 启动超时"
    return 1
}

# 检查并自动生成 HTTPS 证书
mkdir -p "$PROJECT_ROOT/certs"
if [ ! -f "$PROJECT_ROOT/certs/key.pem" ] || [ ! -f "$PROJECT_ROOT/certs/cert.pem" ]; then
    print_message $YELLOW "🔑 未检测到 HTTPS 证书，正在自动生成自签名证书..."
    openssl req -newkey rsa:2048 -nodes -keyout "$PROJECT_ROOT/certs/key.pem" -x509 -days 365 -out "$PROJECT_ROOT/certs/cert.pem" -subj "/C=CN/ST=Beijing/L=Beijing/O=SmartInput Development/OU=Development Team/CN=localhost/emailAddress=dev@smartinput.local" -addext "subjectAltName=DNS:localhost,IP:127.0.0.1,IP:::1,IP:192.168.137.122,IP:192.168.3.17"
    if [ $? -eq 0 ]; then
        print_message $GREEN "✅ 自签名证书生成成功！"
        print_message $YELLOW "💡 macOS 用户如需让浏览器插件信任此证书，请在终端执行："
        print_message $BLUE "sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain $PROJECT_ROOT/certs/cert.pem"
        print_message $YELLOW "执行后请重启 Chrome 浏览器。"
    else
        print_message $RED "❌ 证书生成失败，请检查 openssl 是否安装。"
        exit 1
    fi
fi

# 构建React管理后台
build_admin() {
    print_message $BLUE "🔨 构建 React 管理后台..."
    
    # 检查管理后台目录
    if [ ! -d "$ADMIN_DIR" ]; then
        print_message $RED "❌ 管理后台目录不存在: $ADMIN_DIR"
        exit 1
    fi
    
    # 进入管理后台目录
    cd "$ADMIN_DIR"
    
    # 检查依赖
    if [ ! -d "node_modules" ]; then
        print_message $YELLOW "📦 安装管理后台依赖..."
        npm install
    fi
    
    # 构建管理后台
    print_message $YELLOW "🔨 构建管理后台..."
    if npm run build; then
        print_message $GREEN "✅ 管理后台构建成功"
    else
        print_message $RED "❌ 管理后台构建失败"
        return 1
    fi
}

# 启动WebSocket服务器
start_server() {
    print_message $BLUE "🚀 启动 WebSocket 服务器..."
    
    # 检查服务器目录
    if [ ! -d "$SERVER_DIR" ]; then
        print_message $RED "❌ 服务器目录不存在: $SERVER_DIR"
        exit 1
    fi
    
    # 检查是否已经在运行
    if [ -f "$SERVER_PID_FILE" ] && kill -0 $(cat "$SERVER_PID_FILE") 2>/dev/null; then
        print_message $YELLOW "⚠️  WebSocket服务器已在运行 (PID: $(cat $SERVER_PID_FILE))"
        return 0
    fi
    
    # 检查端口3001是否被占用
    if check_port 3001; then
        print_message $YELLOW "⚠️  端口3001已被占用，尝试停止现有进程..."
        pkill -f "node.*dist/index.js" || true
        sleep 2
    fi
    
    # 进入服务器目录并启动
    cd "$SERVER_DIR"
    
    # 检查依赖
    # if [ ! -d "node_modules" ]; then
    print_message $YELLOW "📦 安装服务器依赖..."
    npm install
    # fi
    

    print_message $YELLOW "🔨 构建服务器..."
    npm run build

    
    # 启动服务器
    nohup npm start > "$SERVER_LOG" 2>&1 &
    local server_pid=$!
    echo $server_pid > "$SERVER_PID_FILE"
    
    # 等待服务器启动
    if wait_for_port 3001 "WebSocket服务器"; then
        print_message $GREEN "✅ WebSocket服务器启动成功 (PID: $server_pid)"
        print_message $BLUE "   📍 地址: http://localhost:3001"
        print_message $BLUE "   📄 日志: $SERVER_LOG"
    else
        print_message $RED "❌ WebSocket服务器启动失败"
        return 1
    fi
}

# 启动移动端应用
start_mobile() {
    print_message $BLUE "📱 启动移动端PWA应用..."
    
    # 检查移动端目录
    if [ ! -d "$MOBILE_DIR" ]; then
        print_message $RED "❌ 移动端目录不存在: $MOBILE_DIR"
        exit 1
    fi
    
    # 检查是否已经在运行
    if [ -f "$MOBILE_PID_FILE" ] && kill -0 $(cat "$MOBILE_PID_FILE") 2>/dev/null; then
        print_message $YELLOW "⚠️  移动端应用已在运行 (PID: $(cat $MOBILE_PID_FILE))"
        return 0
    fi
    
    # 寻找可用端口 (3000, 3002, 3003...)
    local port=3000
    while check_port $port && [ $port -lt 3010 ]; do
        port=$((port + 1))
        if [ $port -eq 3001 ]; then  # 跳过服务器端口
            port=3002
        fi
    done
    
    if [ $port -ge 3010 ]; then
        print_message $RED "❌ 无法找到可用端口启动移动端应用"
        return 1
    fi
    
    # 进入移动端目录并启动
    cd "$MOBILE_DIR"
    
    # 检查依赖
    if [ ! -d "node_modules" ]; then
        print_message $YELLOW "📦 安装移动端依赖..."
        npm install
    fi
    
    # 启动移动端应用
    nohup npm run dev -- --host 0.0.0.0 --port $port > "$MOBILE_LOG" 2>&1 &
    local mobile_pid=$!
    echo $mobile_pid > "$MOBILE_PID_FILE"
    
    # 等待移动端应用启动
    if wait_for_port $port "移动端应用"; then
        print_message $GREEN "✅ 移动端应用启动成功 (PID: $mobile_pid)"
        print_message $BLUE "   📍 地址: http://localhost:$port"
        print_message $BLUE "   📄 日志: $MOBILE_LOG"
        
        # 自动打开浏览器
        if command -v open >/dev/null 2>&1; then
            print_message $YELLOW "🌐 正在打开浏览器..."
            open "http://localhost:$port"
        elif command -v xdg-open >/dev/null 2>&1; then
            print_message $YELLOW "🌐 正在打开浏览器..."
            xdg-open "http://localhost:$port"
        fi
    else
        print_message $RED "❌ 移动端应用启动失败"
        return 1
    fi
}

# 启动管理后台应用
start_admin() {
    print_message $BLUE "🛠️  启动管理后台应用..."
    
    # 检查管理后台目录
    if [ ! -d "$ADMIN_DIR" ]; then
        print_message $RED "❌ 管理后台目录不存在: $ADMIN_DIR"
        exit 1
    fi
    
    # 检查是否已经在运行
    if [ -f "$ADMIN_PID_FILE" ] && kill -0 $(cat "$ADMIN_PID_FILE") 2>/dev/null; then
        print_message $YELLOW "⚠️  管理后台应用已在运行 (PID: $(cat $ADMIN_PID_FILE))"
        return 0
    fi
    
    # 检查端口3002是否被占用
    if check_port 3002; then
        print_message $YELLOW "⚠️  端口3002已被占用，尝试停止现有进程..."
        pkill -f "vite.*admin-panel" || true
        sleep 2
    fi
    
    # 进入管理后台目录并启动
    cd "$ADMIN_DIR"
    
    # 检查依赖
    if [ ! -d "node_modules" ]; then
        print_message $YELLOW "📦 安装管理后台依赖..."
        npm install
    fi
    
    # 启动管理后台应用
    nohup npm run dev > "$ADMIN_LOG" 2>&1 &
    local admin_pid=$!
    echo $admin_pid > "$ADMIN_PID_FILE"
    
    # 等待管理后台应用启动
    if wait_for_port 3002 "管理后台应用"; then
        print_message $GREEN "✅ 管理后台应用启动成功 (PID: $admin_pid)"
        print_message $BLUE "   📍 地址: https://localhost:3002"
        print_message $BLUE "   📄 日志: $ADMIN_LOG"
        
        # 自动打开浏览器
        if command -v open >/dev/null 2>&1; then
            print_message $YELLOW "🌐 正在打开浏览器..."
            open "https://localhost:3002"
        elif command -v xdg-open >/dev/null 2>&1; then
            print_message $YELLOW "🌐 正在打开浏览器..."
            xdg-open "https://localhost:3002"
        fi
    else
        print_message $RED "❌ 管理后台应用启动失败"
        return 1
    fi
}

# 主函数
main() {
    print_message $GREEN "🎯 SmartInput 服务启动脚本"
    print_message $BLUE "================================"
    
    # 构建React管理后台
    if ! build_admin; then
        print_message $RED "❌ 管理后台构建失败，退出"
        exit 1
    fi
    
    # 初始化数据目录
    print_message $BLUE "📁 初始化数据目录..."
    mkdir -p "$SERVER_DIR/data"
    if [ ! -f "$SERVER_DIR/data/smartinput-data.json" ]; then
        print_message $YELLOW "📝 创建初始数据文件..."
        echo '{"devices":{},"pairings":{},"pairingCodes":{},"stats":{"lastSave":0,"totalDevices":0,"totalPairings":0}}' > "$SERVER_DIR/data/smartinput-data.json"
    fi
    
    # 启动服务器
    if ! start_server; then
        print_message $RED "❌ 服务器启动失败，退出"
        exit 1
    fi
    
    # 启动移动端应用
    if ! start_mobile; then
        print_message $RED "❌ 移动端应用启动失败，退出"
        exit 1
    fi

    # 启动管理后台应用
    if ! start_admin; then
        print_message $RED "❌ 管理后台应用启动失败，退出"
        exit 1
    fi
    
    print_message $BLUE "================================"
    print_message $GREEN "🎉 所有服务启动成功！"
    print_message $BLUE ""
    print_message $BLUE "📊 服务状态:"
    print_message $BLUE "   🖥️  WebSocket服务器: http://localhost:3001"
    print_message $BLUE "   📱 移动端应用: 已在浏览器中打开"
    print_message $BLUE "   🛠️  管理后台: https://localhost:3002"
    print_message $BLUE ""
    print_message $BLUE "🛠️  管理命令:"
    print_message $BLUE "   停止服务: ./stop.sh"
    print_message $BLUE "   重启服务: ./restart.sh"
    print_message $BLUE "   查看状态: ./status.sh"
    print_message $BLUE ""
    print_message $YELLOW "💡 提示: 使用 Ctrl+C 或运行 ./stop.sh 来停止所有服务"
}

# 执行主函数
main "$@"
